package com.college.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import static org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace;

/**
 * @author 小C工作室
 */
@Slf4j
public class ObjectUtil {

    private ObjectUtil() {
    }

    /**
     * 判断对象是否为空，如果为空则创建按一个对象返回，否则直接返回
     *
     * @param object
     * @param tClass
     * @param <T>
     * @return
     */
    public static <T> T filterObjectNull(T object, Class<? extends T> tClass) {
        if (isEmpty(object)) {
            try {
                object = tClass.newInstance();
            } catch (InstantiationException | IllegalAccessException e) {
                log.error(getStackTrace(e));
                e.printStackTrace();
            }
        }
        return object;
    }


    /**
     * 对象属性复制类型转换
     *
     * @param source      源对象
     * @param targetClass 目标类型
     * @param <T>
     * @param <H>
     * @return
     */
    public static <T, H> H objectCopyProperties(T source, Class<H> targetClass) {
        H h = null;
        try {
            h = targetClass.newInstance();
            BeanUtils.copyProperties(source, h);
        } catch (InstantiationException | IllegalAccessException e) {
            log.error(getStackTrace(e));
            e.printStackTrace();
        }
        return h;
    }

    /**
     * 对象空判断
     *
     * @param obj
     * @return
     */
    public static boolean isEmpty(Object obj) {
        if (obj == null) {
            return true;
        }
        if (obj.getClass().isArray()) {
            return Array.getLength(obj) == 0;
        }
        if (obj instanceof CharSequence) {
            return ((CharSequence) obj).length() == 0;
        }
        if (obj instanceof Collection) {
            return ((Collection<?>) obj).isEmpty();
        }
        if (obj instanceof Map) {
            return ((Map<?, ?>) obj).isEmpty();
        }
        // else
        return false;
    }

    public static boolean isNotEmpty(Object obj) {
        return !isEmpty(obj);
    }

    /**
     * @param sourceBean 被提取的对象bean
     * @param targetBean 用于合并的对象bean
     * @return targetBean 合并后的对象
     * @Description: 该方法是用于相同对象不同属性值的合并，如果两个相同对象中同一属性都有值，
     * 那么sourceBean中的值会覆盖tagetBean重点的值
     * @return: Object
     */
    public static <T> T combineObject(T sourceBean, T targetBean) {
        if (targetBean == null) {
            return sourceBean;
        }
        Class sourceBeanClass = sourceBean.getClass();
        Class targetBeanClass = targetBean.getClass();
        Field[] sourceFields = sourceBeanClass.getDeclaredFields();
        Field[] targetFields = targetBeanClass.getDeclaredFields();
        for (int i = 0; i < sourceFields.length; i++) {
            Field sourceField = sourceFields[i];
            Field targetField = targetFields[i];
            sourceField.setAccessible(true);
            targetField.setAccessible(true);
            try {
                if (Boolean.FALSE.equals(sourceField.get(sourceBean) == null)) {
                    targetField.set(targetBean, sourceField.get(sourceBean));
                }
            } catch (IllegalArgumentException | IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return targetBean;
    }


    /**
     * 判断对象属性是否全部有值（string／Integer/List类型）
     *
     * @param object
     * @return
     */
    public static boolean objCheckIsNull(Object object) {
        Class clazz = (Class) object.getClass(); // 得到类对象
        Field fields[] = clazz.getDeclaredFields(); // 得到所有属性
        boolean flag = true; //定义返回结果，默认为true
        for (Field field : fields) {
            field.setAccessible(true);
            Object fieldValue = null;
            Type fieldType = null;
            String fieldName = null;
            try {
                fieldValue = field.get(object); //得到属性值
                fieldType = field.getType();//得到属性类型
                fieldName = field.getName(); // 得到属性名
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            if (fieldValue == null) {  //只要有一个属性值为null 就返回false 表示对象属性有为null的
                flag = false;
                break;
            }
            if (fieldType.equals(Integer.class) && (Integer) fieldValue == 0) {
                flag = false; //Integer默认属性值为0
                break;
            }
            if (List.class.isAssignableFrom((Class<?>) fieldType)) {
                try {
                    Class<?> clzz = fieldValue.getClass();
                    //反射调用获取到list的size方法来获取到集合的大小
                    Method sizeMethod = clzz.getDeclaredMethod("size");
                    //集合长度
                    int size = (int) sizeMethod.invoke(fieldValue);
                    if (size < 1) {
                        flag = false; //list中条数为0
                        break;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return flag;
    }

    public static List<String> objToList(Object obj){
        List<String> result = new ArrayList<>();
        if (obj instanceof ArrayList<?>) {
            for (Object o : (List<?>) obj) {
                result.add(String.class.cast(o));
            }
        }
        return result;
    }

}
